/**
 * COPYRIGHT Robam Industrial Group Co. Ltd. Limited
 * All right reserved.
 */
package com.robam.cloud.common.util.dingtalk;

import com.alibaba.fastjson.JSONObject;
import com.alipay.api.internal.util.codec.Base64;
import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.OapiRobotSendRequest;
import com.dingtalk.api.response.OapiRobotSendResponse;
import com.robam.cloud.common.bean.xxljob.entity.DingTalkMsgModule;
import com.robam.cloud.common.bean.xxljob.entity.DingTalkRobot;
import com.robam.cloud.common.util.StringUtil;
import com.taobao.api.ApiException;
import lombok.extern.slf4j.Slf4j;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.List;

/**
 * @Description
 * @Author 薛铁琪
 * @CreateTime 2020-11-03 16:18
 * @Version 1.0
 */
@Slf4j
public class DingtalkUtil {
    private static final String TEXT_MESSAGE_TYPE = "text";
    private static final String LINK_MESSAGE_TYPE = "link";
    private static final String MARKDOWN_MESSAGE_TYPE = "markdown";
    private static final String ACTIONCARD_MESSAGE_TYPE = "actionCard";
    private static final String FEEDCARD_MESSAGE_TYPE = "feedCard";


    private static OapiRobotSendResponse sendTextMsg(String secret, String serverUrl, String textContent, Boolean all, String[] mobilLists) {
        Long timestamp = System.currentTimeMillis();
        String sign = getSign(timestamp, secret);
        if (StringUtil.isEmpty(sign)) {
            return null;
        }
        serverUrl = serverUrl + "&timestamp=" + timestamp + "&sign=" + sign;
        DingTalkClient client = new DefaultDingTalkClient(serverUrl);
        OapiRobotSendRequest request = new OapiRobotSendRequest();
        request.setMsgtype(TEXT_MESSAGE_TYPE);
        OapiRobotSendRequest.Text text = new OapiRobotSendRequest.Text();
        text.setContent(textContent);
        request.setText(text);


        OapiRobotSendRequest.At at = new OapiRobotSendRequest.At();
        at.setAtMobiles(Arrays.asList(mobilLists));
        // isAtAll类型如果不为Boolean，请升级至最新SDK
        at.setIsAtAll(all);
        request.setAt(at);


        OapiRobotSendResponse response = null;
        try {
            response = client.execute(request);
        } catch (ApiException e) {
            log.error("钉钉消息推送失败{}", e);
            return null;
        }
        return response;
    }


    private static OapiRobotSendResponse sendLinkMsg(String secret, String serverUrl, String linkContent, String picUrl, String title, String text, Boolean all, String[] mobilLists) {
        Long timestamp = System.currentTimeMillis();
        String sign = getSign(timestamp, secret);
        if (StringUtil.isEmpty(sign)) {
            return null;
        }
        serverUrl = serverUrl + "&timestamp=" + timestamp + "&sign=" + sign;
        DingTalkClient client = new DefaultDingTalkClient(serverUrl);
        OapiRobotSendRequest request = new OapiRobotSendRequest();
        request.setMsgtype(LINK_MESSAGE_TYPE);
        OapiRobotSendRequest.Link link = new OapiRobotSendRequest.Link();
        link.setMessageUrl(linkContent);
        link.setPicUrl(picUrl);
        link.setTitle(title);
        link.setText(text);
        request.setLink(link);


        OapiRobotSendRequest.At at = new OapiRobotSendRequest.At();
        at.setAtMobiles(Arrays.asList(mobilLists));
        // isAtAll类型如果不为Boolean，请升级至最新SDK
        at.setIsAtAll(all);
        request.setAt(at);


        OapiRobotSendResponse response = null;
        try {
            response = client.execute(request);
        } catch (ApiException e) {
            log.error("钉钉消息推送失败{}", e);
            return null;
        }
        return response;
    }


    private static OapiRobotSendResponse sendMarkdownMsg(String secret, String serverUrl, String title, String text, Boolean all, String[] mobilLists) {
        Long timestamp = System.currentTimeMillis();
        String sign = getSign(timestamp, secret);
        if (StringUtil.isEmpty(sign)) {
            return null;
        }
        serverUrl = serverUrl + "&timestamp=" + timestamp + "&sign=" + sign;
        DingTalkClient client = new DefaultDingTalkClient(serverUrl);
        OapiRobotSendRequest request = new OapiRobotSendRequest();


        request.setMsgtype(MARKDOWN_MESSAGE_TYPE);
        OapiRobotSendRequest.Markdown markdown = new OapiRobotSendRequest.Markdown();
        markdown.setTitle(title);
        markdown.setText(text);
        request.setMarkdown(markdown);


        OapiRobotSendRequest.At at = new OapiRobotSendRequest.At();
        at.setAtMobiles(Arrays.asList(mobilLists));
        // isAtAll类型如果不为Boolean，请升级至最新SDK
        at.setIsAtAll(all);
        request.setAt(at);


        OapiRobotSendResponse response = null;
        try {
            response = client.execute(request);
        } catch (ApiException e) {
            log.error("钉钉消息推送失败{}", e);
            return null;
        }
        return response;
    }


    private static OapiRobotSendResponse sendActionCardMsg(String secret,
                                                           String serverUrl,
                                                           String title,
                                                           String text,
                                                           String btnOrientation,
                                                           List<OapiRobotSendRequest.Btns> btns,
                                                           String hideAvatar,
                                                           String singleTile,
                                                           String singleUrl,
                                                           Boolean all,
                                                           String[] mobilLists) {
        Long timestamp = System.currentTimeMillis();
        String sign = getSign(timestamp, secret);
        if (StringUtil.isEmpty(sign)) {
            return null;
        }
        serverUrl = serverUrl + "&timestamp=" + timestamp + "&sign=" + sign;
        DingTalkClient client = new DefaultDingTalkClient(serverUrl);
        OapiRobotSendRequest request = new OapiRobotSendRequest();


        request.setMsgtype(ACTIONCARD_MESSAGE_TYPE);
        OapiRobotSendRequest.Actioncard actioncard = new OapiRobotSendRequest.Actioncard();
        actioncard.setTitle(title);
        actioncard.setText(text);
        actioncard.setBtnOrientation(btnOrientation);
        actioncard.setBtns(btns);
        actioncard.setHideAvatar(hideAvatar);
        actioncard.setSingleTitle(singleTile);
        actioncard.setSingleURL(singleUrl);
        request.setActionCard(actioncard);


        OapiRobotSendRequest.At at = new OapiRobotSendRequest.At();
        at.setAtMobiles(Arrays.asList(mobilLists));
        // isAtAll类型如果不为Boolean，请升级至最新SDK
        at.setIsAtAll(all);
        request.setAt(at);


        OapiRobotSendResponse response = null;
        try {
            response = client.execute(request);
        } catch (ApiException e) {
            log.error("钉钉消息推送失败{}", e);
            return null;
        }
        return response;
    }


    private static OapiRobotSendResponse sendFeedCardMsg(String secret, String serverUrl, List<OapiRobotSendRequest.Links> links, Boolean all, String[] mobilLists) {
        Long timestamp = System.currentTimeMillis();
        String sign = getSign(timestamp, secret);
        if (StringUtil.isEmpty(sign)) {
            return null;
        }
        serverUrl = serverUrl + "&timestamp=" + timestamp + "&sign=" + sign;
        DingTalkClient client = new DefaultDingTalkClient(serverUrl);
        OapiRobotSendRequest request = new OapiRobotSendRequest();


        request.setMsgtype(FEEDCARD_MESSAGE_TYPE);
        OapiRobotSendRequest.Feedcard feedcard = new OapiRobotSendRequest.Feedcard();
        feedcard.setLinks(links);
        request.setFeedCard(feedcard);


        OapiRobotSendRequest.At at = new OapiRobotSendRequest.At();
        at.setAtMobiles(Arrays.asList(mobilLists));
        // isAtAll类型如果不为Boolean，请升级至最新SDK
        at.setIsAtAll(all);
        request.setAt(at);


        OapiRobotSendResponse response = null;
        try {
            response = client.execute(request);
        } catch (ApiException e) {
            log.error("钉钉消息推送失败{}", e);
            return null;
        }
        return response;
    }


    private static String getSign(Long timestamp, String secret) {
        String stringToSign = timestamp + "\n" + secret;
        Mac mac = null;
        try {
            mac = Mac.getInstance("HmacSHA256");
        } catch (NoSuchAlgorithmException e) {
            log.error("钉钉消息推送签名失败{}", e);
            return null;
        }
        try {
            mac.init(new SecretKeySpec(secret.getBytes("UTF-8"), "HmacSHA256"));
        } catch (InvalidKeyException e) {
            log.error("钉钉消息推送签名失败{}", e);
            return null;
        } catch (UnsupportedEncodingException e) {
            log.error("钉钉消息推送签名失败{}", e);
            return null;
        }
        byte[] signData = new byte[0];
        try {
            signData = mac.doFinal(stringToSign.getBytes("UTF-8"));
        } catch (UnsupportedEncodingException e) {
            log.error("钉钉消息推送签名失败{}", e);
            return null;
        }
        String sign = null;
        try {
            sign = URLEncoder.encode(new String(Base64.encodeBase64(signData)), "UTF-8");
        } catch (UnsupportedEncodingException e) {
            log.error("钉钉消息推送签名失败{}", e);
            return null;
        }
        return sign;
    }


    public static OapiRobotSendResponse sendMsg(DingTalkRobot dingTalkRobot, DingTalkMsgModule dingTalkMsgModule) {
        if (TEXT_MESSAGE_TYPE.equals(dingTalkMsgModule.getMsgType())) {
            return sendTextMsg(dingTalkRobot.getSecret(), dingTalkRobot.getServerUrl(), dingTalkMsgModule.getTextContent(), dingTalkMsgModule.getAll(), dingTalkMsgModule.getMobile().split(","));
        }

        if (LINK_MESSAGE_TYPE.equals(dingTalkMsgModule.getMsgType())) {
            return sendLinkMsg(dingTalkRobot.getSecret(), dingTalkRobot.getServerUrl(), dingTalkMsgModule.getLinkContent(), dingTalkMsgModule.getLinkPicUrl(), dingTalkMsgModule.getLinkTitile(), dingTalkMsgModule.getLinkText(), dingTalkMsgModule.getAll(), dingTalkMsgModule.getMobile().split(","));
        }


        if (MARKDOWN_MESSAGE_TYPE.equals(dingTalkMsgModule.getMsgType())) {
            return sendMarkdownMsg(dingTalkRobot.getSecret(), dingTalkRobot.getServerUrl(), dingTalkMsgModule.getMarkdownTitle(), dingTalkMsgModule.getMarkdownText(), dingTalkMsgModule.getAll(), dingTalkMsgModule.getMobile().split(","));
        }

        if (ACTIONCARD_MESSAGE_TYPE.equals(dingTalkMsgModule.getMsgType())) {
            String actioncardBtns = dingTalkMsgModule.getActioncardBtns();
            List<OapiRobotSendRequest.Btns> btns = JSONObject.parseArray(actioncardBtns, OapiRobotSendRequest.Btns.class);
            return sendActionCardMsg(dingTalkRobot.getSecret(), dingTalkRobot.getServerUrl(), dingTalkMsgModule.getActioncardTitle(), dingTalkMsgModule.getActioncardText(), dingTalkMsgModule.getActioncardBtnorientation(), btns, dingTalkMsgModule.getActioncardHideavatar(), dingTalkMsgModule.getActioncardSingletile(), dingTalkMsgModule.getActioncardSingleurl(), dingTalkMsgModule.getAll(), dingTalkMsgModule.getMobile().split(","));
        }


        if (FEEDCARD_MESSAGE_TYPE.equals(dingTalkMsgModule.getMsgType())) {
            String links = dingTalkMsgModule.getFeedcardLinks();
            List<OapiRobotSendRequest.Links> linksList = JSONObject.parseArray(links, OapiRobotSendRequest.Links.class);
            return sendFeedCardMsg(dingTalkRobot.getSecret(), dingTalkRobot.getServerUrl(), linksList, dingTalkMsgModule.getAll(), dingTalkMsgModule.getMobile().split(","));
        }
        log.warn("定义的钉钉消息发送类型不匹配无法发送");
        return null;
    }
}
